package ${pknDAO}.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import ${packageName}.common.DaoException;
import ${packageName}.common.PaginationSupport;
import ${packageName}.core.BaseDAO;
import ${packageName}.dao.${className}DAO;
import ${pknEntity}.${className};

/**
 * 
 * ${className}DAO 接口实现类
 * 
 * @author 00fly
 * @version [版本号, ${date?date}]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */

@SuppressWarnings("unchecked")
public class ${className}DAOImpl extends BaseDAO<${className}> implements ${className}DAO
{
    
    /**
     * <默认构造函数>
     */
    public ${className}DAOImpl()
    {
        super();
    }
    
    /**
     * 构造whereClause
     * 
     * @param criteria
     * @return
     */
    private String buildWhereClause(${className} criteria)
    {
        StringBuilder whereClause = new StringBuilder();
        if (criteria.${pk.getMethod}() != null)
        {
            whereClause.append(" and ${pk.name}=?");
        }
        <#list columns as column>
        if (criteria.${column.getMethod}() != null)
        {
            whereClause.append(" and ${column.name}=?");
        }
        </#list> 
        if (whereClause.length() > 4)
        {
            return whereClause.substring(4);
        }
        return "";
    }
    
    /**
     * 构造whereParams
     * 
     * @param criteria
     * @return
     * 
     */
    private List<Object> buildWhereParams(${className} criteria)
    {
        List<Object> whereParams = new ArrayList<Object>();
        if (criteria.${pk.getMethod}() != null)
        {
            whereParams.add(criteria.${pk.getMethod}());
        }
        <#list columns as column>
        if (criteria.${column.getMethod}() != null)
        { 
            whereParams.add(criteria.${column.getMethod}());
        }
        </#list> 
        return whereParams;
    }
    
    /**
     * 根据条件删除数据
     * 
     * @param criteria 条件对象
     * @return
     * @throws DaoException
     */
    @Override
    public int deleteByCriteria(${className} criteria)
        throws DaoException
    {
        try
        {
            StringBuilder sql = new StringBuilder("delete from ${tableName}");
            String whereClause = buildWhereClause(criteria);
            List<Object> whereParams = buildWhereParams(criteria);
            if (StringUtils.isNotEmpty(whereClause))
            {
                sql.append(" where ").append(whereClause);
            }
            return update(sql.toString(), whereParams.toArray());
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据主键id删除数据
     * 
     * @param id 主键
     * @return
     * @throws DaoException
     */
    @Override
    public int deleteById(${pk.javaType} id)
        throws DaoException
    {
        try
        {
            String sql = "delete from ${tableName} where ${pk.name}=?";
            return update(sql, id);
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据主键id列表删除数据
     * 
     * @param ids 主键列表
     * @return
     * @throws DaoException
     */
    @Override
    public int deleteById(${pk.javaType}[] ids)
        throws DaoException
    {
        try
        {
            ${pk.javaType} idsArr[][] = new ${pk.javaType}[ids.length][1];
            for (int i = 0; i < ids.length; i++)
            {
                idsArr[i][0] = ids[i];
            }
            String sql = "delete from ${tableName} where ${pk.name}=?";
            return batch(sql, idsArr).length;
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据主键id列表删除数据
     * 
     * @param ids 主键列表
     * @return
     * @throws DaoException
     */
    @Override
    public int deleteById(List<${pk.javaType}> ids)
        throws DaoException
    {
        try
        {
            ${pk.javaType} idsArr[][] = new ${pk.javaType}[ids.size()][1];
            for (int i = 0; i < ids.size(); i++)
            {
                idsArr[i][0] = ids.get(i);
            }
            String sql = "delete from ${tableName} where ${pk.name}=?";
            return batch(sql, idsArr).length;
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 增加记录(插入全字段)
     * 
     * @param bean 待插入对象
     * @return
     * @throws DaoException
     */
    @Override
    public int insert(${className} bean)
        throws DaoException
    {
        try
        {
            String sql =
                "insert into ${tableName} (<#list columns as column>${column.name}<#if column_has_next>,</#if> </#list>) values(<#list columns as column>?<#if column_has_next>, </#if></#list>)";
            return update(sql, 
                <#list columns as column>bean.${column.getMethod}()<#if column_has_next>,</#if>
                </#list>);  
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 增加记录(仅插入非空字段)
     * 
     * @param bean 待插入对象
     * @return
     * @throws DaoException
     */
    @Override
    public int insertSelective(${className} bean)
        throws DaoException
    {
        try
        {
            StringBuilder columns = new StringBuilder();
            StringBuilder values = new StringBuilder();
            List<Object> params = new ArrayList<Object>(); 
            <#list columns as column>
            if (bean.${column.getMethod}() != null)
            {
                columns.append(", ${column.name}");
                values.append(", ?");
                params.add(bean.${column.getMethod}());
            }
            </#list>
            StringBuilder sql = new StringBuilder("insert into ${tableName} (").append(columns.substring(1)).append(")");
            sql.append(" values(").append(values.substring(1)).append(")");
            return update(sql.toString(), params.toArray());
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 查询全部
     * 
     * @return
     * @throws DaoException
     */
    @Override
    public List<${className}> queryAll()
        throws DaoException
    {
        try
        {
            String sql =
                "select ${pk.name}<#list columns as column>, ${column.name}</#list> from ${tableName}";
            return query(${className}.class, sql);
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据条件查询
     * 
     * @param criteria 条件对象
     * @return
     * @throws DaoException
     */
    @Override
    public List<${className}> queryByCriteria(${className} criteria)
        throws DaoException
    {
        try
        {
            StringBuilder sql =
                new StringBuilder(
                    "select ${pk.name}<#list columns as column>, ${column.name}</#list> from ${tableName} ");
            String whereClause = buildWhereClause(criteria);
            List<Object> whereParams = buildWhereParams(criteria);
            if (StringUtils.isNotEmpty(whereClause))
            {
                sql.append(" where ").append(whereClause);
            }
            return query(${className}.class, sql.toString(), whereParams.toArray());
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据id查找数据
     * 
     * @param id 主键
     * @return
     * @throws DaoException
     */
    @Override
    public ${className} queryById(${pk.javaType} id)
        throws DaoException
    {
        try
        {
            String sql =
                "select ${pk.name}<#list columns as column>, ${column.name}</#list> from ${tableName} where ${pk.name}=?";
            return (${className})queryFirst(${className}.class, sql, id);
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据条件分页查询
     * 
     * @param criteria 条件对象
     * @param pageNo 页号
     * @param pageSize 页大小
     * @return
     * @throws DaoException
     */
    @Override
    public PaginationSupport<${className}> queryForPagination(${className} criteria, int pageNo, int pageSize)
        throws DaoException
    {
        try
        {
            StringBuilder sql =
                new StringBuilder(
                    "select ${pk.name}<#list columns as column>, ${column.name}</#list> from ${tableName}");
            String whereClause = buildWhereClause(criteria);
            List<Object> whereParams = buildWhereParams(criteria);
            if (StringUtils.isNotEmpty(whereClause))
            {
                sql.append(" where ").append(whereClause);
            }
            return queryForPagination(${className}.class, sql.toString(), pageNo, pageSize, whereParams.toArray());
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据条件查询数据条数
     * 
     * @param criteria 条件对象
     * @return
     * @throws DaoException
     */
    @Override
    public long queryTotal(${className} criteria)
        throws DaoException
    {
        try
        {
            StringBuilder sql = new StringBuilder("select count(1) from ${tableName}");
            String whereClause = buildWhereClause(criteria);
            List<Object> whereParams = buildWhereParams(criteria);
            if (StringUtils.isNotEmpty(whereClause))
            {
                sql.append(" where ").append(whereClause);
            }
            return queryForLong(sql.toString(), whereParams.toArray());
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据复杂条件更新全字段数据
     * 
     * @param bean 待更新对象
     * @param criteria 条件对象
     * @return
     * @throws DaoException
     */
    @Override
    public int updateByCriteria(${className} bean, ${className} criteria)
        throws DaoException
    {
        try
        {
            StringBuilder sql =
                new StringBuilder(
                    "update ${tableName} set <#list columns as column>${column.name}=?<#if column_has_next>, </#if></#list>");
            List<Object> params = new ArrayList<Object>();
            <#list columns as column>
            params.add(bean.${column.getMethod}());
            </#list>
            String whereClause = buildWhereClause(criteria);
            List<Object> whereParams = buildWhereParams(criteria);
            if (StringUtils.isNotEmpty(whereClause))
            {
                sql.append(" where ").append(whereClause);
            }
            params.addAll(whereParams);
            return update(sql.toString(), params.toArray());
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据复杂条件更新非空字段数据
     * 
     * @param bean 待更新对象
     * @param criteria 条件对象
     * @return
     * @throws DaoException
     */
    @Override
    public int updateByCriteriaSelective(${className} bean, ${className} criteria)
        throws DaoException
    {
        try
        {
            StringBuilder sql = new StringBuilder("update ${tableName} set");
            StringBuilder columns = new StringBuilder();
            List<Object> params = new ArrayList<Object>();
            <#list columns as column>
            if (bean.${column.getMethod}() != null)
            {
                columns.append(", ${column.name}=?");
                params.add(bean.${column.getMethod}());
            }
            </#list>
            sql.append(columns.substring(1));
            
            String whereClause = buildWhereClause(criteria);
            List<Object> whereParams = buildWhereParams(criteria);
            if (StringUtils.isNotEmpty(whereClause))
            {
                sql.append(" where ").append(whereClause);
            }
            params.addAll(whereParams);
            return update(sql.toString(), params.toArray());
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据id更新全部数据
     * 
     * @param bean 待更新对象
     * @return
     * @throws DaoException
     */
    @Override
    public int updateById(${className} bean)
        throws DaoException
    {
        try
        {
            String sql =
                "update ${tableName} set <#list columns as column>${column.name}=?<#if column_has_next>, </#if></#list> where ${pk.name}=?";
            return update(sql,
                <#list columns as column>bean.${column.getMethod}(),
                </#list>bean.${pk.getMethod}());
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
    /**
     * 根据id更新非空字段数据
     * 
     * @param bean 待更新对象
     * @return
     * @throws DaoException
     */
    @Override
    public int updateByIdSelective(${className} bean)
        throws DaoException
    {
        try
        {
            StringBuilder sql = new StringBuilder("update ${tableName} set");
            StringBuilder columns = new StringBuilder();
            List<Object> params = new ArrayList<Object>();
            <#list columns as column>
            if (bean.${column.getMethod}() != null)
            {
                columns.append(", ${column.name}=?");
                params.add(bean.${column.getMethod}());
            }
            </#list>
            sql.append(columns.substring(1));
            sql.append(" where ${pk.name}=?");
            params.add(bean.${pk.getMethod}());
            return update(sql.toString(), params.toArray());
        }
        catch (SQLException e)
        {
            throw new DaoException(e.getMessage(), e.getCause());
        }
    }
    
}